/*
 * Created by iiro on 21.7.2016.
 *
 * BottomBar library for Android
 * Copyright (c) 2016 Iiro Krankka (http://github.com/roughike).
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.roughike.bottombar;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.List;

import ohos.agp.utils.Color;
import ohos.global.resource.Entry;
import ohos.global.resource.RawFileEntry;
import ohos.global.resource.Resource;
import ohos.javax.xml.stream.XMLInputFactory;
import ohos.javax.xml.stream.XMLStreamException;
import ohos.javax.xml.stream.XMLStreamReader;
import ohos.app.Context;

class TabParser {
    private static final String TAB_TAG = "tab";

    private static final int AVG_NUMBER_OF_TABS = 5;

    private final Context context;

    private final BottomBarTab.Config defaultTabConfig;

    private  XMLStreamReader parser;

    private List<BottomBarTab> tabs = null;

    /**
     *
     * @param context ohos.app.Context
     * @param defaultTabConfig BottomBarTab.Config
     * @param tabsXmlPath like "resources/rawfile/xml/customtabs.xml", xml file must be in rawfile dir
     */
    TabParser(Context context, BottomBarTab.Config defaultTabConfig, String tabsXmlPath) {
        this.context = context;
        this.defaultTabConfig = defaultTabConfig;

        RawFileEntry rawFileEntry = context.getResourceManager().getRawFileEntry(tabsXmlPath);
        if (Entry.Type.FILE != rawFileEntry.getType()) {
            throw new TabParserException("tabsXmlPath not a file");
        }
        try {
            Resource resource = rawFileEntry.openRawFile();
            XMLInputFactory xmlInputFactory = XMLInputFactory.newInstance();
            this.parser = xmlInputFactory.createXMLStreamReader(resource);
        } catch (Exception e) {
            throw new TabParserException(e.getMessage());
        }
    }

    List<BottomBarTab> parseTabs() {
        if (tabs == null) {
            tabs = new ArrayList<>(AVG_NUMBER_OF_TABS);
            try {
                int eventType;
                while(parser.hasNext()){
                    eventType = parser.next();
                    if (eventType == XMLStreamReader.START_ELEMENT && TAB_TAG.equals(parser.getLocalName())) {
                        BottomBarTab bottomBarTab = parseNewTab(parser, tabs.size());
                        tabs.add(bottomBarTab);
                    }
                }
            }catch (XMLStreamException e) {
                throw new TabParserException(e.getMessage());
            }

        }

        return tabs;
    }

    private BottomBarTab parseNewTab(XMLStreamReader parser, int containerPosition) {
        BottomBarTab workingTab = tabWithDefaults();
        workingTab.setIndexInContainer(containerPosition);

        final int numberOfAttributes = parser.getAttributeCount();
        for (int i = 0; i < numberOfAttributes; i++) {

            String attrName = parser.getAttributeName(i).getLocalPart();
            switch (attrName) {
                case TabAttribute.IDTAG:
                    workingTab.setTag(parser.getAttributeValue(i));
                    break;
                case TabAttribute.ICON:
                    workingTab.setIconResId(ResHelper.invokeResId(context, parser.getAttributeValue(i)));
                    break;
                case TabAttribute.ICON_SELECTED:
                    workingTab.setIconSelectedResId(ResHelper.invokeResId(context, parser.getAttributeValue(i)));
                    break;
                case TabAttribute.TITLE:
                    // xml中仅支持string硬编码形式，不支持引用形式<$string:name>
                    workingTab.setTitle(parser.getAttributeValue(i));
                    break;
                case TabAttribute.INACTIVE_COLOR:
                    // xml中value仅支持<#FFFFFF>字符串形式color，不支持<$color:red>形式
                    workingTab.setInActiveColor(Color.getIntColor(parser.getAttributeValue(i)));
                    break;
                case TabAttribute.ACTIVE_COLOR:
                    workingTab.setActiveColor(Color.getIntColor(parser.getAttributeValue(i)));
                    break;
                case TabAttribute.BAR_COLOR_WHEN_SELECTED:
                    workingTab.setBarColorWhenSelected(Color.getIntColor(parser.getAttributeValue(i)));
                    break;
                case TabAttribute.BADGE_BACKGROUND_COLOR:
                    workingTab.setBadgeBackgroundColor(Color.getIntColor(parser.getAttributeValue(i)));
                    break;
                case TabAttribute.BADGE_HIDES_WHEN_ACTIVE:
                    boolean badgeHidesWhenActive = Boolean.parseBoolean(parser.getAttributeValue(i));
                    workingTab.setBadgeHidesWhenActive(badgeHidesWhenActive);
                    break;
                case TabAttribute.IS_TITLELESS:
                    boolean isTitleless = Boolean.parseBoolean(parser.getAttributeValue(i));
                    workingTab.setIsTitleless(isTitleless);
                    break;
            }
        }

        return workingTab;
    }

    private BottomBarTab tabWithDefaults() {
        BottomBarTab tab = new BottomBarTab(context);
        tab.setConfig(defaultTabConfig);

        return tab;
    }

    @Retention(RetentionPolicy.SOURCE)
    @interface TabAttribute {
        String IDTAG = "idtag";
        String ICON = "icon";
        String ICON_SELECTED = "iconSelected";
        String TITLE = "title";
        String INACTIVE_COLOR = "inActiveColor";
        String ACTIVE_COLOR = "activeColor";
        String BAR_COLOR_WHEN_SELECTED = "barColorWhenSelected";
        String BADGE_BACKGROUND_COLOR = "badgeBackgroundColor";
        String BADGE_HIDES_WHEN_ACTIVE = "badgeHidesWhenActive";
        String IS_TITLELESS = "iconOnly";
    }

    @SuppressWarnings("WeakerAccess")
    private static class TabParserException extends RuntimeException {
        // This class is just to be able to have a type of Runtime Exception that will make it clear where the error originated.
        TabParserException(String message) {

        }
    }

}
